package com.lry.sso.gateway.bean;

import com.alibaba.fastjson.JSON;
import org.springframework.util.StringUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 请求包装类
 * @author 李瑞益
 * @date 2020-01-14 15:54
 */
public class RequestWrapper extends HttpServletRequestWrapper {

    private ByteArrayOutputStream cacheBytes;
    // 用于存储请求参数
    private Map params = new HashMap<>();


    private String body;

    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        renewBody(request);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream(),"UTF-8"));
    }

    /**
     * 添加参数到map中
     * @param name
     * @param value
     */
    public void setParameter(String name, Object value) {
        if (value != null) {
            System.out.println(value);
            if (value instanceof String[]) {
                params.put(name, (String[]) value);
            } else if (value instanceof String) {
                params.put(name, new String[]{(String) value});
            } else {
                params.put(name, new String[]{String.valueOf(value)});
            }
        }
    }

    /**
     * 重写getParameter，代表参数从当前类中的map获取
     * @param name
     * @return
     */
    @Override
    public String getParameter(String name) {
        Object v = params.get(name);
        if (v == null)
        {
            return null;
        }
        else if (v instanceof String[])
        {
            String[] strArr = (String[])v;
            if (strArr.length > 0)
            {
                return strArr[0];
            }
            else
            {
                return null;
            }
        }
        else if (v instanceof String)
        {
            return (String)v;
        }
        else
        {
            return v.toString();
        }
    }

//    /**
//     * 重写getParameterValues方法，从当前类的 map中取值
//     * @param name
//     * @return
//     */
//    @Override
//    public String[] getParameterValues(String name) {
//        return params.get(name);
//    }

    /**
     * 添加参数到map中
     * @param extraParams
     */
    public void addParams(Map<String, Object> extraParams) {
        if (extraParams == null) {
            return;
        }
        for (Map.Entry<String, Object> entry : extraParams.entrySet()) {
            setParameter(entry.getKey(), entry.getValue());
        }
    }

    /**
     * 获取请求参数
     * @return
     */
    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(this.params.keySet());
    }


    /**
     * 读取body的值
     *
     * @param request
     */
    private void renewBody(HttpServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
        body = stringBuilder.toString();
    }

    /**
     * 获取请求体
     * @return 请求体body
     */
    public String getBody(){
        return body;
    }

    public void setBody(String body) {
        if (!StringUtils.isEmpty(body)) {
            this.params = JSON.parseObject(body);
            this.body = body;
        }
    }
}
